/**
 * ECP Web开发树控件.
 * Copyright(c) 2012-2020 YGSoft.Inc
 * 对第三方jstree进行封装，建议前端内部使用
 * @author zhengxianwei 
 * @date 2016-05-13
 */
define(["jquery","ecp.service","jstree","ecp.utils"],function($,ecp,jstree,utils){
	/**
	 * 默认参数.
	 */
	var defaultOptions = {
			plugins: ["types", "search","create_node"]
	};
	
	/**
	 * 声明EcpTree对象.
	 * @param {Object} control 控件的jQuery对象，即占位符。
	 * @param {option} option 控件的属性对象
	 */
	var EcpTree = function(control,option){
		if(!control || control.length === 0){return;}
		//初始化
		this._init(control,option);
		//渲染控件
		this._render();
	}
	/**
	 * 通过原型定义相关方法，比如渲染、赋值等等.
	 */
	EcpTree.prototype = {
			/**
			 * 初始化.
	    	 * @param {Object} option 控件的属性对象
			 */
			_init: function(control,option){
				this.control = control;
				var dOpt = control.attr("data-option");
				if(dOpt && dOpt.length !== 0){
					dOpt = $.parseJSON(dOpt);
				}else{
					dOpt = {};
				}
				var opt = this.option = $.extend(true,{},defaultOptions,dOpt,option);
				if(opt){
					if(!opt.idField && opt.treeValueField){
						this.option.idField = opt.treeValueField;
					}
					if(!opt.textField && opt.treeTextField){
						this.option.textField = opt.treeTextField;
					}
				}
				//多选
				if(opt.multiple){
					this.option.plugins.push("checkbox");
	    		}
			},
			
			/**
	    	 * 初始化渲染.
	    	 */
			_render: function(){
				this._renderTree();
	    	},
	    	
			/**
			 * 设置树节点数据回调.
			 */
			setTreeDatas: function(handler){
				if($.isFunction(handler)){
					this.option.treeDatas = handler;
				}
			},
			
	    	/**
	    	 * 渲染树控件.
	    	 */
	    	_renderTree: function(){
	    		var me = this,
	    			opt = me.option,
	    			treeObj = me.control;
	    		var treeOption = {
 						"treeCodeField":option.treeCodeField,
 						"treeTextField":option.treeTextField,
 						"treeType":option.treeType,
 						"treeValueField":option.treeValueField,
 						"treeFieldName":option.buildTreeField,
 						"treeCodePolicy":option.treeCodePolicy
 				};
	    		var initTreeFn = function(resultData){
	    			var treeData = me.getJsTreeJson(resultData);
	 				treeObj.data("treeOption",treeOption);
	 				treeObj.jstree("destroy");
	 				treeObj.jstree({
	 					"core" : {
	 				      "themes" : {
	 				        "responsive": false,
					        "icons":false
	 				      },
	 				      'data': treeData
	 				    },
	 				    "types" : {
	 				      "default" : {
	 				        "icon" : "fa fa-folder icon-warning icon-lg"
	 				      },
	 				      "file" : {
	 				        "icon" : "fa fa-file icon-warning icon-lg"
	 				      }
	 				    },
	 				    "plugins": opt.plugins
	 				});
	 				me._bindTreeEvent();
	    		}
	    		var data = opt.data;
	    		var treeDatas = this.option.treeDatas;
	    		if($.isFunction(treeDatas)){
	    			treeDatas.call(this, this.option, initTreeFn);
	    		}else if(data && data.length !== 0){
	    			initTreeFn(data);
	    		}
	    		//默认选中树节点
	    		var selectDatas = this.initData();
	    		if(selectDatas && selectDatas.length !== 0){
	    			var idField = opt.idField;
	    			if(opt.multiple){
	    				$.each(selectDatas,function(i,d){
		    				treeObj.jstree("select_node",d[idField]);
		    			})
	    			}else{
	    				treeObj.jstree("select_node",selectDatas[idField]);
	    			}
	    		}
	    	},
	    	initData: function(){
	    		return [];
	    	},
			/**
			 * 绑定的树事件.
			 */
			_bindTreeEvent: function(){
				var me = this,
	    			opt = me.option,
					container = me.winContainer,
					treeObj = me.control;
		    	//展开缩起节点.
		    	$("#btn_entityTreeExpand", container).off("click").on("click", function(){
		 			var first = treeObj.jstree('get_container_ul').children(":first").attr("id");
		 			if (treeObj.jstree("is_open",first)) {
		 				treeObj.jstree("close_all");
		 			} else {
		 				treeObj.jstree("open_all");
		 			}
		 		});
		    	
	    		//树的展开事件.
				treeObj.bind("open_node.jstree",function(event,data){
					//顶层节点展开不做处理.
	    		      this.node = data.node;
	    		});
	    		  
	    		//选择树节点事件
				treeObj.bind("select_node.jstree",function(event,data){
	    			var seleceds = data.selected;
	    			if(seleceds && seleceds.length !== 0){
	    				for(var i = 0,j=seleceds.length; i<j; i++){
	    					if(!selectNodeDatas[seleceds[i]]){
	    						selectNodeDatas[seleceds[i]] = data.node;
	    					}
	    				}
	    			}
	    		});
				//绑定用户设置的事件
				if(utils.notEmpty(me.treeEvents)){
					$.each(me.treeEvents,function(){
						treeObj.bind(this.event,this.handler);
					})
				}
			},
			
	    	/**
	    	 * 构建jstree 能识别的json。
	    	 */
	    	getJsTreeJson: function(data){
	    		var me = this;
	    		var data = data;
	    		if (!data || !data.length) return [];
	    		var node,pNode,jsTreeData = [],
	    			treeCodeField = me.option.treeOptions.treeCodeField;
	    		//按itemcode排序.
	    		data.sort(function(a, b){
	    			return a[treeCodeField].localeCompare(b[treeCodeField]);
	    		}); 
	    		for(var i=0,j=data.length; i<j; i++){
	    			node = me.createNode(data[i],data);
	    			pNode = me.getpNode(node,jsTreeData);
	    			if(pNode){
	    				pNode.children.push(node);
	    			}else{
	    				jsTreeData.push(node);
	    			}
	    		}
	    		return jsTreeData;
	    	},
	    	/**
	    	 * 绑定树事件
	    	 */
	    	bindTreeEvent: function(event,handler){
	    		if(utils.notEmpty(event) && utils.notEmpty(handler)){
	    			if(!this.treeEvents){this.treeEvents = [];}
	    			this.treeEvents.push({event:event,handler:handler});
	    		}
	    	},
	    	/**
	    	 * 解除树事件
	    	 */
	    	unBindTreeEvent: function(event){
	    		if(utils.notEmpty(event)){
	    			var te = this.treeEvents;
	    			if(te && te.length !== 0){
	    				for(var i=te.length-1; i>=0; i--){
	    					if(te[i].event === event){
	    						te.removeAt(i);
	    					}
	    				}
	    			}
	    		}
	    	},
	    	/**
	    	 * 获取上级节点.
	    	 */
	    	getpNode: function(node,jsTreeData){
	    	    for(var i=0,j=jsTreeData.length; i<j; i++){
	    	    	var pNode = jsTreeData[i]
	    	    	if(node.pid == pNode.id){
	    	    		return pNode;
	    	    	}else if(pNode.children.length){
	    	    		pNode = this.getpNode(node, pNode.children);
	    	    	}
	    	    } 
	    	    return pNode;
	    	},
	    	/**
	    	 * 获取所有子孙节点.
	    	 */
	    	getChildrenNode: function(pNode,jsTreeData){
	    	    for(var i=0,j=jsTreeData.length; i<j; i++){
	    	    	var node = jsTreeData[i]
	    	    	if(pNode.id == node.pid){
	    	    		return node;
	    	    	}else if(node.children.length){
	    	    		node = this.getChildrenNode(pNode, node.children);
	    	    	}
	    	    } 
	    	    return node;
	    	},
	    	 
	    	/**
	    	 * 创建节点
	    	 */
	    	createNode: function(data, treeAttr){
	    	   var node = data;
	    	   var treeOpt = this.option.treeOptions,
	    	   	   treeCodeField = treeOpt.treeCodeField,
	    	   	   treeTextField = treeOpt.treeTextField,
	    	   	   treeCodePolicy = treeOpt.treeCodePolicy;
	    	   node.id = data[treeCodeField];
	    	   node.text = data[treeTextField];
	    	   var nodelen = treeCodePolicy.split("-");
	    	   var treelen = 0;
	    	   for(var i=0,j=nodelen.length; i<j; i++){
	    		   if(node[treeCodeField].length == treelen + parseInt(nodelen[i])){
	    			   break;
	    		   } else{
	    			   treelen = treelen + parseInt(nodelen[i]);
	    		   }
	    	   }
    	   	   node.pid = data[treeCodeField].substr(0,treelen);
	    	   node.children = [];
	    	   return node;  
	    	},

	    	/**
	    	 * 设置option.
	    	 * @param {Object} option 控件属性
	    	 */
	    	setOption:function(option){
	    		if(!option || !$.isPlainObject(option) || $.isEmptyObject(option)){
	    			return;
	    		}
	    		this.option = $.extend(true,this.option,option);
	    	},
	    	
	    	/**
	    	 * 获取options
	    	 * @return {Object} option 控件属性对象
	    	 */
	    	getOption:function(){
	    		return this.option;
	    	}
	};
	(function($) {
		var old = $.fn.ecpTree;
		$.fn.ecpTree = function(option){
			var me = this;
			if(!me || me.length === 0){
				if(window.console){
					window.console.error("ecp.component.jstree渲染控件的占位符不存在，请确认页面jquery对象是否存在？");
				}
				return;
			}
			option = option || {};
			//如果第一个参数传入的是对象或空则初始化空件，如果传入的是字符串，则认为是调用里面的内部方法。
			if (typeof(option) === "object") {
				this.each(function() {
					var instanceOptions = $.extend({}, option, true);
					var instance = new EcpTree($(this), instanceOptions);
					this.ecpTree = instance;
				});
				return this[0].ecpTree;
			}
		};
		$.fn.ecpTree.Constructor = EcpTree;
		$.fn.ecpTree.noConflict = function() {
			$.fn.ecpTree = old;
			return this;
		};
	}(jQuery));
	return EcpTree;
});